import React from 'react';
import {
  Form,
  Input,
  Button,
  DatePicker,
  Select,
  Table,
  Icon,
  Radio,
  InputNumber,
  Checkbox,
  Modal,
  message,
  notification,
  Affix,
  Upload,
  Col,
  Row,
} from 'antd';
import globalConfig from 'config.js';
import $ from 'jquery';
import Logger from 'utils/Logger';
import ajax from 'utils/ajax';
import 'utils/index';
import FieldConverterFactory from '../FieldConverter';
import loginVerify from 'utils/loginVerify';


const FormItem = Form.Item;
const ButtonGroup = Button.Group;

const logger = Logger.getLogger('InnerTable');
let flag = 1;


/**
 * 内部表格组件
 */
class InnerTable extends React.Component {

  // 很多时候都要在antd的组件上再包一层

  modalActionState={
    None:0,
    Insert:1,
    Update:2,
    Delete:3,
    View:4,
    Allot:5,
  };

  defaultState={
    modalVisible: false,  // modal是否可见,
    modalForm:false,//是否是查看
    modalTitle: '新增',  // modal标题
    modalState: this.modalActionState.None,  //用来标识当前modal的操作状态
    selectedRowKeys: [],  // 当前有哪些行被选中, 这里只保存key
    selectedRows: [],  // 当前有哪些行被选中, 保存完整数据
  };

 

  constructor(props) {
    super(props);
    this.state={
      size: 'default',
    }
    $.extend(this.state,this.defaultState);
  }

  /**
   * InnerTable组件的重render有两种可能:
   * 1. 上层组件调用的render方法, 这个时候会触发componentWillReceiveProps方法
   * 2. 自身状态变化引起的重新render
   * 注意区分
   *
   * 对于第一种情况, 要将组件的状态还原到初始状态
   *
   * @param nextProps
   */
  componentWillReceiveProps = (nextProps) => {
    logger.debug('receive new props and try to render, nextProps=%o', nextProps);
    // 其实传入的props和当前的props可能是一样的, 这个方法不会判断修改才触发
    // 要自己判断props是否有变化
    if (nextProps.tableLoading === true) {
      // 所有状态都要手动还原到初始值
      // 这个方法里setState不会触发render
      this.setState(this.defaultState);
    }
  }

  resetFields = () => {
    // console.log(this.props.form)
    this.props.form.resetFields();
  }

  /**
   * 点击新增按钮, 弹出一个内嵌表单的modal
   *
   * @param e
   */
  onClickInsert = (e) => {
    // console.log("哈哈哈哈点击新增了")
    e.preventDefault();
    this.handleInsertBefore(this);
    this.resetFields();
    this.setState({modalVisible: true, modalTitle: '新增', modalState: this.modalActionState.Insert ,modalForm:false});
  }

  /**
   * 点击新增之前处理数据
   */
  handleInsertBefore = () =>{
    // console.log("hello handleInsertBefore ~~")
  }

  /**
   * 点击更新按钮, 弹出一个内嵌表单的modal
   * 注意区分单条更新和批量更新
   *
   * @param e
   */
  onClickUpdate = (e) => {
    e.preventDefault();
    this.resetFields();

    //常规更新不支持批量操作

    logger.debug('update single record, and fill original values');
    var fieldsValue = this.state.selectedRows[0];
    this.dealUpdateData(fieldsValue);
    let fieldsObj={};
    for(var item in fieldsValue){
      let fieldsKey=item;
      let fieldsItemValue=fieldsValue[item];
      fieldsObj[fieldsKey]=fieldsItemValue;
    }
     this.setState({ updateId: this.state.selectedRowKeys[0] });
     var state={ modalVisible: true, modalTitle: '更新', modalState: this.modalActionState.Update,modalForm:false };
     this.setState(state,()=>{
      this.props.form.setFieldsValue(fieldsObj);
     });
     
  }

  /**
   * 点击查看,被继承用的
   * @param e
   */
  dealUpdateData=(fieldsValue)=>{

  }

  //处理错误信息
  handleErrorMsg = (errorMsg) => {
    // 对于错误信息, 要很明显的提示用户, 这个通知框要用户手动关闭
    notification.error({
      message: '出错啦!',
      description: `请联系管理员, 错误信息: ${errorMsg}`,
      duration: 0,
    });

  };



  /**
   * 点击删除按钮, 弹出一个确认对话框
   * 注意区分单条删除和批量删除
   *
   * @param e
   */
  onClickDelete = (e) => {
    e.preventDefault();
    const name = '删除后此信息将无法找回，是否确认删除？';
    Modal.confirm({
      title: this.state.selectedRowKeys.length > 1 ? '确认批量删除' : '确认删除',
      content: name,
      // 这里注意要用箭头函数, 否则this不生效
      onOk: () => {
        this.handleDelete();
      },
    });
  }


  /**
   * 隐藏modal
   */
  hideModal = () => {
    this.setState({ modalVisible: false });
  }

  /**
   * 生成表单, 每次迭代一个 field 的时候调用的, 可以在编辑的时候, 对 form 表单回显的数据进行处理
   * @param data
   * @param field
   */
  preDealData = (data,field) => {

  }

  hideModalInner=()=>{
    this.setState({ modalInnerVisible: false });
  }

  handleModalInnerOk=()=>{
    this.setState({ modalInnerVisible: false });
  }

  /**
   * 点击modal中确认按钮的回调
   */
  handleModalOk = () => {
    // console.log("哈哈");
    // 将表单中的undefined去掉
    // 表单传过来的主键是逗号分隔的字符串, 这里转换成数组
    const {modalForm} =this.state;
    if(!modalForm){

      this.props.form.validateFieldsAndScroll((err, values) => {
        if (!err) {
          const newObj = {};
          const primaryKeyArray = [];
          const oldObj = this.props.form.getFieldsValue();
          // console.log('oldObj',oldObj)
          oldObj.key = oldObj.keysk;
          delete oldObj.keysk;
          // console.log('oldObj',oldObj)
          for (const key in oldObj) {
            if (!oldObj[key])
              continue;

            if (key === this.primaryKey && typeof oldObj[key] === 'string') {
              for (const str of oldObj[key].split(', ')) {
                // 按schema中的约定, 主键只能是int/varchar
                if (this.primaryKeyType === 'int') {
                  primaryKeyArray.push(parseInt(str));
                } else {
                primaryKeyArray.push(str);
                }
              }
            } else {
              newObj[key] = oldObj[key];
            }
          }
      
          if (this.primaryKey && primaryKeyArray.length > 0) {
            newObj[this.primaryKey] = primaryKeyArray;
          }

          if (this.state.modalState==this.modalActionState.Update)
          {
            if (this.primaryKey) {
            newObj[this.primaryKey] = this.state.selectedRowKeys[0];
            }
          }
          if (this.state.modalState==this.modalActionState.Insert) {
            this.handleInsert(newObj);
          }
          else if (this.state.modalState==this.modalActionState.Update) {
            this.handleUpdate(newObj);
          }
        }
      })
    }
  }

  /**
   * 请求之前，先处理数据
   * @param obj
   * @returns {*}
   */
  handleData = (obj) => {
    return obj;
  }

  // 真正去处理新增数据
  handleInsert = (obj) => {

    var url = this.props.tableConfig.insertUrl?this.props.tableConfig.insertUrl: `/${this.props.tableName}/create`;

    logger.debug('handleInsert: url = %s, obj = %o', url, obj);

    var data = this.handleData({ url: url, params: obj, actionState: this.modalActionState.Insert });
    console.log(13214,data);
    if(!data){
      return;
    }
    this.doOperation({
      url: data.url,
      params:data.params,
      operationText: '正在新增...',
      successMsg: {
        message: '新增成功',
        description: `新增1条数据`
      },
      errorMsg: {
        message: '新增失败',
        description: `请联系管理员处理`
      }
    });


  }

  /**
   * 真正去更新数据
   */
  handleUpdate = (obj) => {
    const keys = obj[this.primaryKey];
    var url = this.props.tableConfig.updateUrl?this.props.tableConfig.updateUrl: `/${this.props.tableName}/update`;

    //obj[this.primaryKey] = undefined;
    obj.id = keys;

    if (obj.createTime) {
      delete obj.createTime;
    }

    var data=this.handleData({url:url,params:obj,actionState:this.modalActionState.Update});
    
    this.doOperation({
      url: data.url,
      params:data.params,
      operationText: '正在更新...',
      successMsg: {
        message: '更新成功',
        description: `更新1条数据`
      },
      errorMsg: {
        message: '更新失败',
        description: `请联系管理员处理`
      }
    });
  }

  /**
   * 真正去删除数据
   */
  handleDelete = () => {
    var url = this.props.tableConfig.deleteUrl?this.props.tableConfig.deleteUrl: `/${this.props.tableName}/delete`;

    logger.debug('handleDelete: url = %s', url);

    var data=this.handleData({url:url,params:{id:this.state.selectedRowKeys.join(',')},actionState:this.modalActionState.Delete});

    this.doOperation({
      url: data.url,
      params:data.params,
      operationText: '正在删除...',
      successMsg: {
        message: '删除成功',
        description: `删除1条数据`
      },
      errorMsg: {
        message: '删除失败',
        description: `请联系管理员处理`
      }
    });
  }

  onFileUpChange=(target)=>{
    // console.log("nimamamama",target)
  }

  doOperation = (param) => {
    const hide = message.loading(param.operationText, 0);
    var _this = this;
    var houZhuis=_this.state.name;
    ajax.post({
      url: param.url,
      params:param.params,
      success: function (res) {  
          if(houZhuis !== "zip" && houZhuis !== undefined){
              notification.error({
                  message: '传输格式错误',
                  description: "请传输zip格式",
              });
              
          }else if(houZhuis === undefined || houZhuis === "zip"){
            hide();
            _this.setState({ modalVisible: false, selectedRowKeys: [] });
            if (res.errorCode == 200) {
              notification.success({
                message: param.successMsg.message,
                description: param.successMsg.description
              });

              _this.props.refresh();  // 更新数据后, 注意刷新下整个页面
              _this.props.refreshTree();  //刷新左侧树
            }
            else {
              _this.handleErrorMsg(res.moreInfo);
            }
          }     
      },
      error: (err) => {
        console.log(err);
      }
    });
  }

  /**
   * 处理表格的选择事件
   *
   * @param selectedRowKeys
   * @param selectedRows
   */
  handleSelectChange = (selectedRowKeys, selectedRows) => {
    this.setState({ selectedRowKeys, selectedRows });
    console.log('selectdata',selectedRows);
    console.log('selectedRowKeys',selectedRowKeys);
  }

  getButtonGroup = function () {
    const tableName = this.props.tableName.toLowerCase();
    let button= null,number=null;
    let isButtondisabled=false;

    if(this.state.selectedRowKeys.length > 0){  // 是否选择
      isButtondisabled=true;
    }

   if(this.state.selectedRowKeys.length > 1){  // 是否选择了多项
      isButtondisabled=false;
    }
    var modulePermssion = loginVerify.getModulePermission(this.props.moduleName);
    // console.log(this.props.moduleName, 'this.props.moduleName');
    console.log('modulePermssion', modulePermssion);
    button = modulePermssion.map((node) => {
      switch (node) {
        case "edit":
        let editName="修改";
        if(this.props.tableConfig.editName){
          editName=this.props.tableConfig.editName;
        }
          if (this.props.tableConfig.showEdit != 0) {
            return (<Radio.Button key="editBtn" disabled={!isButtondisabled} onClick={this.onClickUpdate}><Icon type="edit" />{editName}
            </Radio.Button>);
          }
          return ("")
        case "delete":
        let deleteName="删除";
        if(this.props.tableConfig.deleteName){
          editName=this.props.tableConfig.deleteName;
        }
          if (this.props.tableConfig.showDelete != 0) {
            return (<Radio.Button key="deleteBtn" disabled={!isButtondisabled} onClick={this.onClickDelete}><Icon type="delete" />{deleteName}</Radio.Button>);
          }
          return ("")
        case "save":
        let addName="新增";
        if(this.props.tableConfig.addName){
          editName=this.props.tableConfig.addName;
        }
          if (this.props.tableConfig.showSave != 0) {
            return (<Button key="saveBtn" type="primary" onClick={this.onClickInsert}><Icon type="plus-circle-o" />{addName}</Button>);
         }
         return ("")
        default:
          return ("");
      }
      });
    // console.log(button)
    return (
      <div className='clearfix'>
        <Radio.Group value={this.state.size}>
          {/* 注意这里, 如果schema中没有定义主键, 不允许update或delete */}
          {this.prepareBeforeToolBar()}
          {/*{this.changeButtonPlace(button,this.props.tableConfig.sortArr)}*/}
          {button}
          {this.prepareToolBar()}
        </Radio.Group>
        <Radio.Group value={this.state.size} style={{float: 'right'}}>
          {this.getSortButtonGroup()}
        </Radio.Group>
      </div>
    )
  }

  getSortButtonGroup = () => {
    const tableName = this.props.tableName.toLowerCase();
    if(this.props.tableConfig.sort){
      this.sort = require(`../../schema/${tableName}/sortSchema.js`);    
      let sortButton=this.sort.map((sort)=>{
        switch(sort.dataType){
          // case "add":
          //   return (<Button key="saveBtn" type="primary" onClick={this.onClickInsert}><Icon type="plus-circle-o" />新增</Button>);
          case "button":
            return (<Radio.Button key={sort.key} value={sort.size}>{sort.title}</Radio.Button>);
          case "output":
            return (<Radio.Button key={sort.key} value={sort.size}>{sort.title}</Radio.Button>);
          case "look":
            return (<Radio.Button key={sort.key} value={sort.size}>{sort.title}</Radio.Button>);
          default:
            break;
        }
      })
      return sortButton;
    }
  }

// 传入一个【0，1，2，3】的数组来进行交换位置
  // changeButtonPlace = (btnArr, sortArr) => {
  //   let newArr = [];
  //   if(sortArr == undefined) {
  //     sortArr=[0, 1, 2, 3];
  //   }
  //   for(let i = 0; i < sortArr.length; i++ ) {
  //     newArr.push(btnArr[sortArr[i]]);
  //   }
  //   return newArr;
  // }

  getBottomGroup = () => {
    return (<Row>
        <Col  style={{ textAlign: 'center',marginTop:'10px'}}>
          {this.prepareBottomToolBar()}
       </Col>
      </Row>
   )
  }

  prepareBottomToolBar = () => {
    return [];
  }

  prepareToolBar = () => {
      return [];
  }

  prepareBeforeToolBar = () => {
      return [];
  }

  prepareColumns = () => {
    this.props.schema.forEach((field) => {
      field.dataIndex = field.key;
      // 当前列是否是主键?
      if (field.primary) {
        this.primaryKey = field.key;
        this.primaryKeyType = field.dataType;
      }
    });

    return this.props.schema;
  }

  preDealTableData=(obj,newObj)=>{
    // if (newObj.children) {
    //   newObj.children.forEach(function(value) {
    //     if (!value.key) {
    //       value.key = value.id;
    //     }
    //   });
    // }
  }

  prepareDataSource = () => {
    // 对数据也要处理一下
    // 每行数据都必须有个key属性, 如果指定了主键, 就以主键为key
    // 否则直接用个自增数字做key
    const newData = [];
    let i = 0;
    let _this=this;
    this.props.data.forEach((obj) => {

      const newObj = Object.assign({}, obj);

      if (this.primaryKey) {
        newObj.key = obj[this.primaryKey];
      } else {
        newObj.key = i;
        i++;
      }

      _this.preDealTableData(obj,newObj); //处理table list 数据
      newData.push(newObj);
    });
    // console.log('newData',newData)
    return newData;
  }

  /**
   * 可重写方法,编辑表单时是否可用
   */
  enableFieldToFrom = (field) => {
    return true;
  }

  prepareModal = () => {
    return this.prepareModalForm();
  }

  getUniqueModal=()=>{

  }

  lookForm = () =>{
    const formItems = [];
    this.props.lookForm.forEach((field,i) => {
      if(this.enableFieldToFrom(field))
      {
          var converter = this.getConverter();
          this.preDealData(this.state.resData, field);
          formItems.push(converter.convert(this, field));
      }
    });
    return (<div className="innerTableCon"><Form layout="horizontal">{formItems}</Form></div>);

  }
  handleUpChange = () => {   //表单上传事件
  }
  houZhui = (name) =>{
    this.setState({
      name
    })
  }
  prepareModalForm = () => {
    // 生成表单项
    const formItems = [];
    // console.log(this.props.formSchema);
    // console.log(this.props);
    this.props.formSchema.forEach((field) => {
      if(this.enableFieldToFrom(field))
      {
          var converter = this.getConverter();
          this.preDealData(this.state.resData, field);
          formItems.push(converter.convert(this, field));
      }
    });
    return (<div className="innerTableCon"><Form layout="horizontal">{formItems}</Form></div>);
  }

  getConverter() {
    var converter = FieldConverterFactory.getConverter(FieldConverterFactory.FormFieldConverter);
    return converter;
  }

  modalInnerTable(){}

  renderModal (option) {
    
  }
  renderFooter = () => {
    console.log(this.props.bottomInfo);
    const bottomInfo = this.props.bottomInfo;
    if(!bottomInfo)
    return '底部信息加载失败......';
    return bottomInfo;
  }

  render() {

    var self = this;

    let rowSelEnable = this.props.tableConfig.rowSelEnable;
    let rowSelection = {};

    if (rowSelEnable == 0) { //表格项是否显示checkBox 为0时不显示
      rowSelection=null;
    }
    else {
      rowSelection = {
        selectedRowKeys: this.state.selectedRowKeys,
        onChange: this.handleSelectChange,
      };
    }
    return (
      <div>
        <div className="db-table-button">
          {this.getButtonGroup()}
          <Modal width={this.props.tableConfig.modalWidth} ref='modal' title={this.state.modalTitle} visible={this.state.modalVisible} onOk={this.handleModalOk}
            onCancel={this.hideModal}>
            {this.state.modalVisible&&this.state.modalForm ? this.lookForm() : this.prepareModal() }
          </Modal>
          {this.modalInnerTable()}
          {this.getUniqueModal()}
        </div>
        <Table rowSelection={rowSelection} columns={this.prepareColumns()} dataSource={this.prepareDataSource()} pagination={false}
          loading={this.props.tableLoading} bordered
          title={this.props.tableConfig.title ? () => this.props.tableConfig.title : false}
          footer={this.props.tableConfig.footer ? this.renderFooter : false}
          scroll={this.props.tableConfig.scroll}
          showHeader={this.props.tableConfig.showHeader}
        />
        <div className = "db-table-bottom-button">
          {this.getBottomGroup()}
        </div>
      </div>
    );
  }

}

export default InnerTable;
